package com.util;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class PubFun {
    /**
     * 计算日期的函数 author: HST
     * 参照日期指当按照年月进行日期的计算的时候，参考的日期，如下例，结果返回2002-03-31
     * <p><b>Example: </b><p>
     * <p>FDate tD=new FDate();<p>
     * <p>Date baseDate =new Date();<p>
     * <p>baseDate=tD.getDate("2000-02-29");<p>
     * <p>Date comDate =new Date();<p>
     * <p>comDate=tD.getDate("1999-12-31");<p>
     * <p>int inteval=1;<p>
     * <p>String tUnit="M";<p>
     * <p>Date tDate =new Date();<p>
     * <p>tDate=PubFun.calDate(baseDate,inteval,tUnit,comDate);<p>
     * <p>System.out.println(tDate.toString());<p>
     * @param baseDate 起始日期
     * @param interval 时间间隔
     * @param unit 时间间隔单位
     * @param compareDate 参照日期
     * @return Date类型变量
     */
    public static Date calDate(Date baseDate, int interval, String unit,
                               Date compareDate)
    {
        Date returnDate = null;

        GregorianCalendar mCalendar = new GregorianCalendar();
        mCalendar.setTime(baseDate);
        if (unit.equals("Y"))
        {
            mCalendar.add(Calendar.YEAR, interval);
        }
        if (unit.equals("M"))
        {
            mCalendar.add(Calendar.MONTH, interval);
        }
        if (unit.equals("D"))
        {
            mCalendar.add(Calendar.DATE, interval);
        }

        if (compareDate != null)
        {
            GregorianCalendar cCalendar = new GregorianCalendar();
            cCalendar.setTime(compareDate);

            int mYears = mCalendar.get(Calendar.YEAR);
            int mMonths = mCalendar.get(Calendar.MONTH);
            int cMonths = cCalendar.get(Calendar.MONTH);
            int cDays = cCalendar.get(Calendar.DATE);

            if (unit.equals("Y"))
            {
                cCalendar.set(mYears, cMonths, cDays);
                if (cCalendar.before(mCalendar))
                {
                    mCalendar.set(mYears + 1, cMonths, cDays);
                    returnDate = mCalendar.getTime();
                }
                else
                {
                    returnDate = cCalendar.getTime();
                }
            }
            if (unit.equals("M"))
            {
                cCalendar.set(mYears, mMonths, cDays);
                if (cCalendar.before(mCalendar))
                {
                    mCalendar.set(mYears, mMonths + 1, cDays);
                    returnDate = mCalendar.getTime();
                }
                else
                {
                    returnDate = cCalendar.getTime();
                }
            }
            if (unit.equals("D"))
            {
                returnDate = mCalendar.getTime();
            }
        }
        else
        {
            returnDate = mCalendar.getTime();
        }

        return returnDate;
    }

    /**
     * 重载计算日期，参数见楼上，add by Minim
     * @param baseDate String
     * @param interval int
     * @param unit String
     * @param compareDate String
     * @return String
     */
    public static String calDate(String baseDate, int interval, String unit,
                                 String compareDate)
    {
        try
        {
            FDate tFDate = new FDate();
            Date bDate = tFDate.getDate(baseDate);
            Date cDate = tFDate.getDate(compareDate);
            return tFDate.getString(calDate(bDate, interval, unit, cDate));
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            return null;
        }
    }
    /**
     * 通过起始日期和终止日期计算以时间间隔单位为计量标准的时间间隔 author: HST
     * <p><b>Example: </b><p>
     * <p>参照calInterval(String  cstartDate, String  cendDate, String unit)，前两个变量改为日期型即可<p>
     * @param startDate 起始日期，Date变量
     * @param endDate 终止日期，Date变量
     * @param unit 时间间隔单位，可用值("Y"--年 "M"--月 "D"--日)
     * @return 时间间隔,整形变量int
     */
    public static int calInterval(Date startDate, Date endDate, String unit)
    {
        int interval = 0;

        GregorianCalendar sCalendar = new GregorianCalendar();
        sCalendar.setTime(startDate);
        int sYears = sCalendar.get(Calendar.YEAR);
        int sMonths = sCalendar.get(Calendar.MONTH);
        int sDays = sCalendar.get(Calendar.DAY_OF_MONTH);
        int sDaysOfYear = sCalendar.get(Calendar.DAY_OF_YEAR);

        GregorianCalendar eCalendar = new GregorianCalendar();
        eCalendar.setTime(endDate);
        int eYears = eCalendar.get(Calendar.YEAR);
        int eMonths = eCalendar.get(Calendar.MONTH);
        int eDays = eCalendar.get(Calendar.DAY_OF_MONTH);
        int eDaysOfYear = eCalendar.get(Calendar.DAY_OF_YEAR);

        if (unit.equals("Y"))
        {
            interval = eYears - sYears;
            if (eMonths < sMonths)
            {
                interval--;
            }
            else
            {
                if (eMonths == sMonths && eDays < sDays)
                {
                    interval--;
                    if (eMonths == 1)
                    { //如果同是2月，校验润年问题
                        if ((sYears % 4) == 0 && (eYears % 4) != 0)
                        { //如果起始年是润年，终止年不是润年
                            if (eDays == 28)
                            { //如果终止年不是润年，且2月的最后一天28日，那么补一
                                interval++;
                            }
                        }
                    }
                }
            }
        }
        if (unit.equals("M"))
        {
            interval = eYears - sYears;
//            interval = interval * 12;
            interval *= 12;

//            interval = eMonths - sMonths + interval;
            interval += eMonths - sMonths;
            if (eDays < sDays)
            {
                interval--;
                //eDays如果是月末，则认为是满一个月
                int maxDate = eCalendar.getActualMaximum(Calendar.DATE);
                if (eDays == maxDate)
                {
                    interval++;
                }
            }
        }
        if (unit.equals("D"))
        {
            long sm = sCalendar.getTimeInMillis();
            long em = eCalendar.getTimeInMillis();
            long rm = em-sm;
            long days = rm/24/3600/1000;
            Long r = new Long(days);
            interval = r.intValue();

        }
        return interval;
    }

    /**
     * 通过起始日期和终止日期计算以时间间隔单位为计量标准的时间间隔，舍弃法 author: HST
     * 起始日期，(String,格式："YYYY-MM-DD")
     * @param cstartDate String
     * 终止日期，(String,格式："YYYY-MM-DD")
     * @param cendDate String
     * 时间间隔单位，可用值("Y"--年 "M"--月 "D"--日)
     * @param unit String
     * 时间间隔,整形变量int
     * @return int
     */
    public static int calInterval(String cstartDate, String cendDate,
                                  String unit)
    {
        FDate fDate = new FDate();
        Date startDate = fDate.getDate(cstartDate);
        Date endDate = fDate.getDate(cendDate);
        int interval = 0;

        GregorianCalendar sCalendar = new GregorianCalendar();
        sCalendar.setTime(startDate);
        int sYears = sCalendar.get(Calendar.YEAR);
        int sMonths = sCalendar.get(Calendar.MONTH);
        int sDays = sCalendar.get(Calendar.DAY_OF_MONTH);
        int sDaysOfYear = sCalendar.get(Calendar.DAY_OF_YEAR);

        GregorianCalendar eCalendar = new GregorianCalendar();
        eCalendar.setTime(endDate);
        int eYears = eCalendar.get(Calendar.YEAR);
        int eMonths = eCalendar.get(Calendar.MONTH);
        int eDays = eCalendar.get(Calendar.DAY_OF_MONTH);
        int eDaysOfYear = eCalendar.get(Calendar.DAY_OF_YEAR);

        if (DateUtils.cTrim(unit).equals("Y"))
        {
            interval = eYears - sYears;

            if (eMonths < sMonths)
            {
                interval--;
            }
            else
            {
                if (eMonths == sMonths && eDays < sDays)
                {
                    interval--;
                    if (eMonths == 1)
                    { //如果同是2月，校验润年问题
                        if ((sYears % 4) == 0 && (eYears % 4) != 0)
                        { //如果起始年是润年，终止年不是润年
                            if (eDays == 28)
                            { //如果终止年不是润年，且2月的最后一天28日，那么补一
                                interval++;
                            }
                        }
                    }
                }
            }
        }
        if (DateUtils.cTrim(unit).equals("M"))
        {
            interval = eYears - sYears;
//            interval = interval * 12;
            interval *= 12;
//            interval = eMonths - sMonths + interval;
            interval += eMonths - sMonths;

            if (eDays < sDays)
            {
                interval--;
                //eDays如果是月末，则认为是满一个月
                int maxDate = eCalendar.getActualMaximum(Calendar.DATE);
                if (eDays == maxDate)
                {
                    interval++;
                }
            }
        }
        if (DateUtils.cTrim(unit).equals("D"))
        {
            long sm = sCalendar.getTimeInMillis();
            long em = eCalendar.getTimeInMillis();
            long rm = em-sm;
            long days = rm/24/3600/1000;
            Long r = new Long(days);
            interval = r.intValue();
            //end by sunpeng
        }
        return interval;
    }

    /**
     * 通过起始日期和终止日期计算以时间间隔单位为计量标准的时间间隔，约进法 author: YangZhao，Minim
     * 起始日期，(String,格式："YYYY-MM-DD")
     * @param cstartDate String
     * 终止日期，(String,格式："YYYY-MM-DD")
     * @param cendDate String
     * 时间间隔单位，可用值("Y"--年 "M"--月 "D"--日)
     * @param unit String
     * 时间间隔,整形变量int
     * @return int
     */
    public static int calInterval2(String cstartDate, String cendDate,
                                   String unit)
    {
        FDate fDate = new FDate();
        Date startDate = fDate.getDate(cstartDate);
        Date endDate = fDate.getDate(cendDate);
        int interval = 0;

        GregorianCalendar sCalendar = new GregorianCalendar();
        sCalendar.setTime(startDate);
        int sYears = sCalendar.get(Calendar.YEAR);
        int sMonths = sCalendar.get(Calendar.MONTH);
        int sDays = sCalendar.get(Calendar.DAY_OF_MONTH);
        int sDaysOfYear = sCalendar.get(Calendar.DAY_OF_YEAR);

        GregorianCalendar eCalendar = new GregorianCalendar();
        eCalendar.setTime(endDate);
        int eYears = eCalendar.get(Calendar.YEAR);
        int eMonths = eCalendar.get(Calendar.MONTH);
        int eDays = eCalendar.get(Calendar.DAY_OF_MONTH);
        int eDaysOfYear = eCalendar.get(Calendar.DAY_OF_YEAR);

        if (DateUtils.cTrim(unit).equals("Y"))
        {
            interval = eYears - sYears;

            if (eMonths > sMonths)
            {
                interval++;
            }
            else
            {
                if (eMonths == sMonths && eDays > sDays)
                {
                    interval++;
                    if (eMonths == 1)
                    { //如果同是2月，校验润年问题
                        if ((sYears % 4) == 0 && (eYears % 4) != 0)
                        { //如果起始年是润年，终止年不是润年
                            if (eDays == 28)
                            { //如果终止年不是润年，且2月的最后一天28日，那么减一
                                interval--;
                            }
                        }
                    }
                }
            }
        }
        if (DateUtils.cTrim(unit).equals("M"))
        {
            interval = eYears - sYears;
            interval *= 12;
            interval += eMonths - sMonths;

            if (eDays > sDays)
            {
                interval++;
                //eDays如果是月末，则认为是满一个月
                int maxDate = eCalendar.getActualMaximum(Calendar.DATE);
                if (eDays == maxDate)
                {
                    interval--;
                }
            }
        }
        if (DateUtils.cTrim(unit).equals("D"))
        {
            long sm = sCalendar.getTimeInMillis();
            long em = eCalendar.getTimeInMillis();
            long rm = em-sm;
            long days = rm/24/3600/1000;
            Long r = new Long(days);
            interval = r.intValue();
        }
        return interval;
    }

    /**
     * 通过传入的日期可以得到所在月的第一天和最后一天的日期 author: LH
     * 日期，(String,格式："YYYY-MM-DD")
     * @param tDate String
     * 本月开始和结束日期，返回String[2]
     * @return String[]
     */
    public static String[] calFLDate(String tDate)
    {
        String MonDate[] = new String[3];
        FDate fDate = new FDate();
        Date CurDate = fDate.getDate(tDate);
        GregorianCalendar mCalendar = new GregorianCalendar();
        mCalendar.setTime(CurDate);
        int Years = mCalendar.get(Calendar.YEAR);
        int Months = mCalendar.get(Calendar.MONTH);
        int FirstDay = mCalendar.getActualMinimum(Calendar.DAY_OF_MONTH);
        int LastDay = mCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        mCalendar.set(Years, Months, FirstDay);
        MonDate[0] = fDate.getString(mCalendar.getTime());
        mCalendar.set(Years, Months, LastDay);
        MonDate[1] = fDate.getString(mCalendar.getTime());
        mCalendar.set(Years, 0, 1);
        MonDate[2] = fDate.getString(mCalendar.getTime());
        return MonDate;
    }




}
